import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import Position from 'src/entities/position.entity';
import { Like, Repository } from 'typeorm';
import {
  CreatePositionDto,
  FindPositionDto,
  SearchPositionDto,
  UpdatePositionDto,
} from './position.dto';
import { isEmpty } from 'lodash';
import { ApiException } from 'src/core/exceptions/api.exception';

@Injectable()
export class PositionService {
  constructor(@InjectRepository(Position) private positionRepository: Repository<Position>) {}

  // 查询列表
  async find(query: FindPositionDto) {
    const { page, size, name, enableStatus, hot, pid } = query;

    const queryBuilder = this.positionRepository
      .createQueryBuilder('position')
      .skip(size * (page - 1))
      .take(size)
      .where((qb) => {
        if (pid !== undefined) {
          qb.andWhere('position.pid = :pid', { pid });
        }
        if (name !== undefined) {
          qb.andWhere('position.name Like :name', { name: `%${name}%` });
        }
        if (enableStatus !== undefined) {
          qb.andWhere('position.enable_status = :status', { status: enableStatus });
        }
        if (hot !== undefined) {
          qb.andWhere('position.hot = :hot', { hot });
        }
      });

    const list = await queryBuilder.getMany();
    const hasFilters =
      pid !== undefined || name !== undefined || enableStatus !== undefined || hot !== undefined;

    if (hasFilters) {
      return { list };
    } else {
      const arr = this.buildTree(list);
      return { list: arr };
    }
  }

  // 搜索职位
  async search(query: SearchPositionDto) {
    const { name } = query;

    return await this.positionRepository.find({
      where: { name: Like(`%${name}%`) },
      select: ['id', 'name'],
    });
  }

  // 新增
  async create(createPositionDto: CreatePositionDto) {
    const position = await this.positionRepository.findOne({
      where: { name: createPositionDto.name },
    });
    if (!isEmpty(position)) {
      throw new ApiException(14001);
    }

    // 父级职位不能设置热门
    if (createPositionDto.pid === 0) {
      createPositionDto.hot = 0;
    }

    const newPosition = this.positionRepository.create(createPositionDto);
    await this.positionRepository.save(newPosition);
  }

  // 更新
  async update(updatePositionDto: UpdatePositionDto) {
    const position = await this.positionRepository.findOne({ where: { id: updatePositionDto.id } });
    if (isEmpty(position)) {
      throw new ApiException(14002);
    }

    const updatePosition = this.positionRepository.merge(position, updatePositionDto);
    await this.positionRepository.save(updatePosition);
  }

  // 转换树形结构
  private buildTree(list: any[], pid = 0) {
    return list
      .filter((item) => item.pid === pid)
      .map((item) => {
        const children = this.buildTree(list, item.id);
        if (children.length > 0) {
          item.children = children;
        }
        return item;
      });
  }
}
